package com.zhucai.credit.utils;

import java.io.IOException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Map.Entry;

import javax.net.ssl.SSLException;

import org.apache.log4j.Logger;
import org.jsoup.Connection;
import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

/**
 * @author jtao
 *
 */
public class StrongJsoup {
	
	private Logger logger = Logger.getLogger(this.getClass());
	
	private static final int TIMEOUT = 60 * 1000;
	
	private Connection conn;
	private String url;
	private int retryTime = 10;
	
	
	private StrongJsoup(String url) {
		this.url = url;
		this.conn = Jsoup.connect(url).timeout(TIMEOUT).ignoreContentType(true).userAgent(
				"Mozilla/5.0 (Windows NT 5.2) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30");
	}
	
	public static StrongJsoup connect(String url) {
		return new StrongJsoup(url);
	}
	
	public Connection getJsoupConn() {
		return conn;
	}

	public StrongJsoup cookie(String name,String value) {
		this.conn.cookie(name, value);
		return this;
	}
	
	public StrongJsoup headers(Map<String,String> headers) {
		for(Entry<String,String> e : headers.entrySet()) {
			this.conn.header(e.getKey(), e.getValue());
		}
		return this;
	}
	
	public Document post(int retryTime) throws SocketException {
		this.retryTime = retryTime;
		return post();
	}

	public Document get(int retryTime) {
		this.retryTime = retryTime;
		return get();
	}
	
	
	public Response execute() {
		for(int i = 0;i < retryTime ; i++) {
			try {
				return conn.execute();
			} catch (SSLException e) {
				// 尝试修复SSL错误, 还给重试机会
				logger.warn("SSL FIX");
				i--;
				conn.validateTLSCertificates(false);
			} catch (UnknownHostException e) {
				logger.warn("===========================");
				logger.warn("网络闪断，休息片刻");
				logger.warn("===========================");
				try {
					Thread.sleep(1000 * 30);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			} catch (IOException e) {
				if(i + 1 < retryTime) {
					logger.warn("请求["+url+"]失败["+i+"]，继续重试", e);
				}
			}
		}
		throw new RuntimeException("请求["+url+"]失败["+retryTime+"]次");
	}
	
	
	public Document get() {
		for(int i = 0;i < retryTime ; i++) {
			try {
				return conn.method(Method.GET).get();
			} catch (SSLException e) {
				// 尝试修复SSL错误, 还给重试机会
				logger.warn("SSL FIX");
				i--;
				conn.validateTLSCertificates(false);
			} catch (UnknownHostException e) {
				logger.warn("===========================");
				logger.warn("网络闪断，休息片刻");
				logger.warn("===========================");
				try {
					Thread.sleep(1000 * 30);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			} catch (IOException e) {
				if(i + 1 < retryTime) {
					logger.warn("请求["+url+"]失败["+i+"]，继续重试", e);
				}
			}
		}
		throw new RuntimeException("请求["+url+"]失败["+retryTime+"]次");
	}
	
	
	public Document post() throws SocketException {
		for(int i = 0;i < retryTime ; i++) {
			try {
				return conn.method(Method.POST).post();
			} catch (SSLException e) {
				// 尝试修复SSL错误, 还给重试机会
				logger.warn("SSL FIX");
				i--;
				conn.validateTLSCertificates(false);
			} catch (IOException e) {
				if(i + 1 < retryTime) {
					logger.warn("请求["+url+"]失败["+i+"]，继续重试", e);
				} else {
					e.printStackTrace();
				}
			}
		}
		throw new SocketException();
	}
	
	

}
